﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Web;
using System.Net.Mail;
using System.Net;

namespace Xpus.Web.Common
{
	/// <summary>
	/// 用于提供发送Email的功能。
	/// </summary>
	public class XpusEmailServer
	{
		/// <summary>
		/// 配置文件的保存位置。
		/// </summary>
		const string EmailServerConfigPath = @"~/App_Data/EmailServers.xml";

		/// <summary>
		/// 获取当前配置的名称。
		/// </summary>
		public string Name { get; private set; }

		/// <summary>
		/// 获取Email服务器主机名。
		/// </summary>
		public string Host { get; private set; }

		/// <summary>
		/// 获取Email服务器端口。
		/// </summary>
		public int Port { get; private set; }

		/// <summary>
		/// 获取用户名。
		/// </summary>
		public string UserName { get; private set; }

		/// <summary>
		/// 获取密码。
		/// </summary>
		public string Password { get; private set; }

		/// <summary>
		/// 获取Email地址。
		/// </summary>
		public string Address { get; private set; }

		/// <summary>
		/// 获取发送方显示的名字。
		/// </summary>
		public string DisplayName { get; private set; }

		/// <summary>
		/// 发送一封Email。
		/// </summary>
		/// <param name="subject">标题。</param>
		/// <param name="body">正文。</param>
		/// <param name="address">目标Email地址。</param>
		public void SendEmail(string subject, string body, string address)
		{
			SmtpClient smtp = new SmtpClient()
			{
				Host = this.Host,
				Port = this.Port,
				Credentials = new NetworkCredential(this.UserName, this.Password),
			};

			using (MailMessage msg = new MailMessage())
			{
				msg.Subject = subject;
				msg.Body = body;
				msg.To.Add(new MailAddress(address));
				msg.From = new MailAddress(this.Address);

				smtp.Send(msg);
			}
		}

		/// <summary>
		/// 从xml配置节点创建EmailServer的实例。
		/// </summary>
		/// <param name="n">xml配置节点。</param>
		XpusEmailServer(XmlNode n)
		{
			this.Name = n.Attributes["name"].Value;
			this.Host = n.Attributes["host"].Value;
			this.Port = int.Parse(n.Attributes["port"].Value);
			this.UserName = n.Attributes["userName"].Value;
			this.Password = n.Attributes["password"].Value;
			this.Address = n.Attributes["address"].Value;
			this.DisplayName = n.Attributes["displayName"].Value;
		}

		/// <summary>
		/// 获取具有指定名字的Email服务器配置。
		/// </summary>
		/// <param name="name">服务器配置名称。</param>
		/// <returns>具有指定名称的Email服务器配置。如果未找到，返回null。</returns>
		public static XpusEmailServer GetServer(string name)
		{
			XpusEmailServerList servers = LoadServerConfig();

			if(servers.ContainsKey(name))
				return servers[name];

			return null;
		}

		/// <summary>
		/// 从配置文件中加载Email服务器配置。
		/// </summary>
		/// <returns>所有Email服务器配置列表。</returns>
		private static XpusEmailServerList LoadServerConfig()
		{
			// 尝试从缓存中获取
			XpusEmailServerList servers = XpusAppDataCache<XpusEmailServerList>.Get(EmailServerConfigPath);
			if (servers != null)
				return servers;

			// 从文件中读取
			servers = new XpusEmailServerList();
			string path = HttpContext.Current.Server.MapPath(EmailServerConfigPath);
			XmlDocument xdoc = new XmlDocument();
			xdoc.Load(path);
			XmlNodeList servernodes = xdoc.SelectNodes("/emailServers/emailServer");
			foreach (XmlNode n in servernodes)
			{
				XpusEmailServer server = new XpusEmailServer(n);
				servers.Add(server.Name, server);
			}

			// 放入缓存
			XpusAppDataCache<XpusEmailServerList>.Set(EmailServerConfigPath, servers);

			return servers;
		}

		/// <summary>
		/// 表示Email服务器列表。集合的键表示配置的名字，值为对应的服务器配置。
		/// </summary>
		class XpusEmailServerList : Dictionary<string, XpusEmailServer>
		{
		}
	}
}
